package datamining.miner.chain;

import java.util.Collection;

import datamining.miner.general.Embedding;

/**
 * This class defines the functionality of a mining step, that encapsulate the
 * whole generation of extensions
 */
public abstract class GenerationStep<ItemType> extends
		GenerationPartialStep<ItemType> {

	private GenerationPartialStep<ItemType> first;

	private final GenerationPartialStep<ItemType> finalize;

	/**
	 * creates a new GenerationStep
	 * 
	 * @param next
	 */
	public GenerationStep(final MiningStep<ItemType> next) {
		super(null);
		finalize = new GenerationPartialStep<ItemType>(next) {
			@Override
			public void call(final SearchLatticeNode<ItemType> node,
					final Collection<Extension<ItemType>> extensions) {
				// just call the next step of the outer
				// GerenationStep
				callNext(node, extensions);
			}

			@Override
			public void call(final SearchLatticeNode<ItemType> node,
					final Embedding<ItemType> embedding) {
				// the final step for Extension<ItemType> generation is
				// nothing else than
				// stop
			}

			@Override
			public void reset() {
				// the final step for resetting is nothing else
				// than stop
			}
		};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * de.parsemis.miner.MiningStep#call(de.parsemis.miner.SearchLatticeNode
	 * , java.util.Collection)
	 */
	@Override
	public void call(final SearchLatticeNode<ItemType> node,
			final Collection<Extension<ItemType>> extensions) {
		if (first != null) {
			first.call(node, extensions);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.parsemis.miner.GenerationPartialStep#call(de.parsemis.miner.
	 * SearchLatticeNode, de.parsemis.graph.Embedding)
	 */
	@Override
	public void call(final SearchLatticeNode node,
			final Embedding embedding) {
		if (first != null) {
			first.call(node, embedding);
		}
	}

	/**
	 * @return the final step for this generation chain
	 */
	public GenerationPartialStep<ItemType> getLast() {
		return finalize;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.parsemis.miner.MiningStep#getNext()
	 */
	@Override
	public MiningStep<ItemType> getNext() {
		return finalize.getNext();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.parsemis.miner.GenerationPartialStep#reset()
	 */
	@Override
	public void reset() {
		if (first != null) {
			first.reset();
		}
	}

	/**
	 * sets the start of the generation chain
	 * 
	 * @param first
	 */
	public void setFirst(final GenerationPartialStep<ItemType> first) {
		this.first = first;
	}

}
